Skip to main content

CNC Example 10: Programming Dynamic CNC Paths

See the CNC10_DynamicPath.project sample project in the installation directory of CODESYS under ..\CODESYS SoftMotion\Examples.

This example shows how a CNC path can be created directly in the application at runtime – not fed with G code from a CNC program object or a file. When this kind of conventional CNC program is compiled, the path data is stored in a SMC_CNC_Data data structure type. This internal data is then compiled in specific global data structures depending on the compile mode (SMC_CNC_REF or SMC_OutQueue).

In compile mode SMC_CNC_REF, the data is stored in an array of SMC_GEOINFO elements. The array in the application code is usually passed to the function block instance SMC_NCDecoder. At runtime, the data is decoded there and stored in a global data structure of type SMC_OUTQUEUE. Then path preprocessing function blocks can be called.

In compile mode SMC_OutQueue, a global data structure (SMC_OUTQUEUE) is generated directly. This data structure in the application code is passed to the interpolator (SMC_Interpolator FB instance). The function block SMC_NCDecoder is not called.

In compile mode FILE, the data is stored in a file. The data is stored as an array of elements of type SMC_GEOINFO and correspond to the data that is generated in compile mode SMC_CNC_REF.

Instead of programming the CNC path, you can program an application code that instantiates a data structure of type SMC_OUTQUEUE at runtime and assigns its values. You program a CNC path that is generated dynamically at runtime. You can pass the data structure to other function block instances (for example to the path preprocessing function blocks or to the function block SMC_Interpolator).

Programming

Tip

The CNCDynamicPath sample project is located in the installation directory of CODESYS. The sample project was developed from the CNConline project. It includes the Path program instead of the graphically programmed Example path. A data structure of type SMC_OUTQUEUE is generated dynamically.

. Declaration:
  • Declare a data structure of type SMC_OUTQUEUE. The data structure contains the CNC path data and is populated dynamically.

    Example: QUEUE

  • Allocate memory for the path with the required amount to SMC_GEOINFO elements.

    Example: BUF

  • Declare a variable of type SMC_GEOINFO with an initial step.

    Example: GEO

. Implementation:
  • An array element of data type SMC_GEOINFO corresponds to a path element in the CNC code. The following steps have to be performed for each element in order to add the element to the SMC_OUTQUEUE:

  • Every array element has a start position that corresponds to the end position of the previous array element.

    Example: GEO.piStartPos.dX := 0; or GEO.piStartPos := GEO.piDestPos;

  • Determine a movement type for each array element.

    Example: GEO.iMoveType := CCLW; or GEO.iMoveType := LIN;

  • Set the parameters of the movement type. This is not required for all movement types.

    Example: For an arc (movement type: CCLW), setting the following positions is required: geoinfo_A[i].dP1 := 200; geoinfo_A[i].dP2 := 100; geoinfo_A[i].dP3 := 50; geoinfo_A[i].dT1 := 0; geoinfo_A[i].dT2 := 90;

  • Insert the calculation of the end position.

    SMC_CalcEndPnt(ADR(GEO));

  • Insert the calculation of the object length.

    SMC_CalcLengthGeo(ADR(GEO));

  • Save the object in QUEUE:

    SMC_AppendObj(POQ:=ADR(QUEUE), PGI:=ADR(GEO));

When the path is created completely, the end markers have to be set: QUEUE.bEndOfList := TRUE;

Tip

Then, when a path preprocessing function block is called, it is required to set the start or end bit for InternMark.

Example 50. Example

CNC path with two path elements

In this example, the arrays are not defined with the X/Y-positions. If this should be an example with two path elements as described, then these arrays would have to have two elements each.

For example, derived from the sample project:

xp:ARRAY[1..2] OF REAL:= [100,50]; yp:ARRAY[1..2] OF REAL:= [0,100];
PROGRAM Path
VAR
        iState : INT;
        QUEUE : SMC_OUTQUEUE;
        BUF : ARRAY[0..49] OF SMC_GEOINFO;
                // Memory allocation
        GEO : SMC_GEOINFO:=(dT1:=0, dT2:=1, dToolRadius:=0, dVel:=100, dVel_End:=100, dAccel:=200, dDecel:=500, iObj_Nr:=0);
                // Initial path element
        n : INT := 0;
        QUEUE.nSize := SIZEOF(BUF);
END_VAR

CASE iState OF
0:
        QUEUE.pbyBuffer := ADR(BUF[0]);
                // Initialize QUEUE
        SMC_SetQueueCapacity(ADR(QUEUE), SIZEOF(BUF));
        iState := iState + 1;

1:
        // Fill QUEUE
        WHILE NOT QUEUE.bFull DO
                // When QUEUE is full, wait until it has been processed by the following FBs
                n := n + 1;
                GEO.iSourceLine_No := n;
                GEO.piStartPos := GEO.piDestPos;
                        // Copying last destination
                GEO.iMoveType := LIN;
                        // Generating linear movement
                GEO.iObjNo := GEO.iObjNo + 1;
                        // Calculating number
                GEO.piDestPos.dX := xp[n];
                        // Generatint position
                GEO.piDestPos.dY := yp[n];
                SMC_CalcLengthGeo(pg := ADR(GEO));
                        // Calculating length of object with the help of the standard function
                SMC_AppendObj(poq:=ADR(QUEUE), pgi:=ADR(GEO));
                        // Appending object to QUEUE
                IF n = SIZEOF(xp)/SIZEOF(xp[1]) THEN
                        // All target positions processed
                        QUEUE.bEndOfList := TRUE;
                        n := 0;
                        iState := 2;
                        EXIT;
                END_IF
        END_WHILE

2:
        //Done
        ;
END_CASE

CheckVel(bExecute:=TRUE , poqDataIn:=ADR(queue)); // Preprocessing


Important

If the SMC_OUTQUEUE data structure is populated with SMC_GEOINFO data and the data structure element was set to bFULL = TRUE, then we do not recommend a further assignment of SMC_GEOINFO data. In this case, the creation of the path is interrupted at runtime until the first element of the SMC_OUTQUEUE data structure is processed in the interpolator. Only then is another element inserted.

Avoid this interruption by allocating enough memory. See variable BUF.

Important

If the data structure SMC_OUTQUEUE is refilled after the first execution, then the interpolator and all preprocessing function blocks (example: SMC_CheckVelocities) have to be restarted by a rising edge at Execute.